package api

import (
	"ginfast/app/system/internal"
	"ginfast/pkg/ginx"
	"runtime"
	"time"

	"github.com/shirou/gopsutil/cpu"
	"github.com/shirou/gopsutil/disk"
	"github.com/shirou/gopsutil/host"
	"github.com/shirou/gopsutil/load"
	"github.com/shirou/gopsutil/mem"
)

// Monitor
type Monitor struct {
}

type server struct {
	CPUAvg15        float64          `json:"cpuAvg15"`
	CPUAvg5         float64          `json:"cpuAvg5"`
	CPUNum          int              `json:"cpuNum"`
	CPUUsed         float64          `json:"cpuUsed"`
	DiskList        []disk.UsageStat `json:"diskList"`
	GoFree          uint64           `json:"goFree"`
	GoHome          string           `json:"goHome"`
	GoName          string           `json:"goName"`
	GoRunTime       uint64           `json:"goRunTime"`
	GoStartTime     string           `json:"goStartTime"`
	GoTotal         uint64           `json:"goTotal"`
	GoUsage         float64          `json:"goUsage"`
	GoUsed          uint64           `json:"goUsed"`
	GoUserDir       string           `json:"goUserDir"`
	GoVersion       string           `json:"goVersion"`
	MemFree         uint64           `json:"memFree"`
	MemTotal        uint64           `json:"memTotal"`
	MemUsage        float64          `json:"memUsage"`
	MemUsed         uint64           `json:"memUsed"`
	SysComputerIP   string           `json:"sysComputerIp"`
	SysComputerName string           `json:"sysComputerName"`
	SysOsArch       string           `json:"sysOsArch"`
	SysOsName       string           `json:"sysOsName"`
}

// ListHandler 列表
func (Monitor) ServerHandler(c *ginx.Context) {
	var data server
	data.CPUNum = runtime.NumCPU()
	if info, err := cpu.Percent(time.Duration(time.Second), false); err == nil {
		data.CPUUsed = internal.Decimal2(info[0])
	}
	if info, err := load.Avg(); err == nil {
		data.CPUAvg5 = internal.Decimal2(info.Load5)
		data.CPUAvg15 = internal.Decimal2(info.Load15)
	}

	if v, err := mem.VirtualMemory(); err == nil {
		data.MemTotal = v.Total
		data.MemUsed = v.Used
		data.MemFree = v.Free
		data.MemUsage = internal.Decimal2(v.UsedPercent)
	}

	var gomen runtime.MemStats
	runtime.ReadMemStats(&gomen)
	data.GoUsed = gomen.Sys
	data.GoUsage = internal.Decimal2(float64(gomen.Sys) / float64(data.MemTotal) * 100)
	if info, err := host.Info(); err == nil {
		data.SysComputerName = info.Hostname
		data.SysOsName = info.OS
		data.SysOsArch = info.KernelArch
		data.SysComputerIP = internal.LocalIP()
	}
	data.GoVersion = runtime.Version()
	data.GoHome = runtime.GOROOT()
	data.GoStartTime = internal.GStartTime.Format("2006-01-02 15:04:05")
	data.GoRunTime = internal.RunTime()
	if info, err := disk.Partitions(true); err == nil {
		for _, v := range info {
			if detail, err := disk.Usage(v.Mountpoint); err == nil {
				detail.Fstype = v.Fstype
				detail.UsedPercent = internal.Decimal2(detail.UsedPercent)
				data.DiskList = append(data.DiskList, *detail)
			}
		}
	}
	c.JSONWriteData(data)
}

func (o Monitor) Routers(r *ginx.RouterGroup) {
	r.GET("/server", o.ServerHandler)
}
